#include <iostream>
#include <string>
#include <signal.h>
#include "../common/httplib.h"
#include "oj_control.hpp"

using namespace httplib;
using namespace ns_control;

// 在全局作用域添加辅助函数
std::string extract_session_id(const std::string& cookie_str) {
    std::string session_id;
    size_t pos = cookie_str.find("session_id=");
    if (pos != std::string::npos) {
        pos += 11; // "session_id=" 的长度
        size_t end = cookie_str.find(';', pos);
        if (end == std::string::npos) end = cookie_str.size();
        session_id = cookie_str.substr(pos, end - pos);
    }
    return session_id;
}

// bool verifyAdmin(const httplib::Request& req) {
//     auto cookie = req.get_header_value("Cookie");
//     std::string session_id = extract_session_id(cookie);

//     // 在数据库中查找 `session_id` 是否属于管理员
//     return _ctl->_model.(session_id);
// }

static Control* _ctl = nullptr;
void AllOnline(int sig)
{
    _ctl->AllOnLineMachine();
}




// 用户路由
int main()
{
    Server svr;  // 服务器对象
    Control ctl;  // 逻辑控制对象

    _ctl = &ctl;
    signal(3, AllOnline);  // 捕捉三号信号 ctrl \ 可以重新上线操作

    // 1.用户获取题目列表数据
    svr.Get("/all_questions", [&ctl](const Request& req, Response& resp){
        std::string html;
        ctl.AllQuestions(html);
        resp.set_content(html, "text/html;charset=utf8");
    });

    // 2.用户获取单题题目内容
    svr.Get(R"(/question/(\d+))", [&ctl](const Request& req, Response& resp){  // (\\d+是正则表达式)
        std::string number = req.matches[1];  // 1对应的就是获取正则表达式中的内容
        std::string html;
        ctl.OneQuestion(number, html);
        resp.set_content(html, "text/html;charset=utf8");
    });

    // 3.用户获取单体解析结果
    svr.Post(R"(/judge/(\d+))", [&ctl](const Request& req, Response& resp){
        std::string number = req.matches[1];  // 1对应的就是获取正则表达式中的内容
        std::string out_json;
        ctl.Judge(number, req.body, out_json);
        resp.set_content(out_json, "application/json;charset=utf8");
    });

    // 扩展1：用户管理系统
    svr.Post("/user", [&ctl](const Request& req, Response& resp){
        std::string out_json;
        ctl.user_control(req.body, out_json, resp);
        resp.set_content(out_json, "application/json;charset=utf8");
    });


    svr.Get("/admin/questions", [&ctl](const Request& req, Response& resp) 
    {
        if (!ctl.verifyAdmin(req)) {  
            resp.set_content("权限不足", "text/plain;charset=utf8");
            return;
        }

        std::vector<Question> questions;
        if (!ctl._model.GetAllQuestions(questions)) { 
            resp.set_content("获取题目列表失败", "text/plain;charset=utf8");
            return;
        }

        // NEW START - 以下是修改后的完整HTML部分
        std::string html = "<html><head><meta charset=\"utf-8\">";
        html += "<link rel=\"stylesheet\" href=\"/css/index.css\">";
        html += "<script src=\"/js/question.js\"></script>";
        html += "<style>#questionManagement * { box-sizing: border-box; }</style>";

        html += "</head><body>";
        
        // 题目管理容器
        html += "<div id='questionManagement'>";
        html += "<h2 style='text-align:center; margin:20px 0'>题目管理</h2>";
        html += "<div style='max-width:1200px; margin:0 auto'>";
        
        // 题目列表
        html += "<h3 style='text-align:center'>题目列表</h3>";
        html += "<script src=\"/js/login.js\" type=\"text/javascript\" charset=\"utf-8\"></script>";
        html += "<script src=\"/js/login.js\"></script>";
        html += "<table style='width:100%; border-collapse:separate; border-spacing:0 15px; margin:20px 0'>";
        for (const auto& q : questions) {
            html += "<tr style='background:#f5f5f5'>";
            html += "<td style='padding:12px; border:1px solid #ddd'>" + q.number + "</td>";
            html += "<td style='padding:12px; border:1px solid #ddd'>" + q.title + "</td>";
            html += "<td style='padding:12px; border:1px solid #ddd'>";
            html += "<button style='color:red; background:none; border:none; cursor:pointer' ";
            html += "onclick=\"deleteQuestion('" + q.number + "')\">删除</button></td>";
            html += "</tr>";
        }
        html += "</table>";

        // 添加新题目表单
        html += "<h3 style='text-align:center; margin:40px 0 20px'>添加新题目</h3>";
        html += "<form onsubmit=\"submitQuestionForm(); return false;\" style='max-width:800px; margin:0 auto'>";
        
        // 第一行输入
        html += "<div style='display:flex; gap:20px; margin-bottom:20px'>";
        html += "<div style='flex:1'>题号: <input type=\"text\" id=\"questionNumber\" required ";
        html += "style='width:100%; padding:8px; margin-top:5px; height:38px'></div>";
        html += "<div style='flex:1'>标题: <input type=\"text\" id=\"title\" required ";
        html += "style='width:100%; padding:8px; margin-top:5px; height:38px'></div>";
        html += "<div style='flex:1'>难度: <input type=\"text\" id=\"star\" required ";
        html += "style='width:100%; padding:8px; margin-top:5px; height:38px'></div>";
        html += "</div>";

        // 大文本区域
        const auto textareaStyle = "width:100%; height:120px; padding:8px; margin:5px 0 20px; resize:vertical";
        html += "<div style='margin-bottom:20px'>";
        html += "<div>描述: <textarea id=\"desc\" style='" + std::string(textareaStyle) + "'></textarea></div>";
        html += "<div>代码头部: <textarea id=\"header\" style='" + std::string(textareaStyle) + "'></textarea></div>";
        html += "<div>代码尾部: <textarea id=\"tail\" style='" + std::string(textareaStyle) + "'></textarea></div>";
        html += "<div>测试输入: <textarea id=\"testInput\" style='" + std::string(textareaStyle) + "'></textarea></div>";
        html += "</div>";

        // 最后一行输入
        html += "<div style='display:flex; gap:20px; margin-top:20px'>";
        html += "<div style='flex:1'>CPU 限制: <input type=\"number\" id=\"cpuLimit\" required ";
        html += "style='width:100%; padding:8px; margin-top:5px; height:38px'></div>";
        html += "<div style='flex:1'>内存限制: <input type=\"number\" id=\"memLimit\" required ";
        html += "style='width:100%; padding:8px; margin-top:5px; height:38px'></div>";
        html += "</div>";

        // 提交按钮
        html += "<button type=\"submit\" style='display:block; width:200px; margin:30px auto; ";
        html += "padding:12px; background:#4CAF50; color:white; border:none; border-radius:4px; cursor:pointer'>";
        html += "添加题目</button>";

        html += "</form>";
        html += "</div></div>"; // 结束container和questionManagement
        html += "</body></html>";
        // NEW END

        resp.set_content(html, "text/html; charset=utf-8");
    });

    // svr.Get("/admin/questions", [&ctl](const Request& req, Response& resp) 
    // {
    //     if (!ctl.verifyAdmin(req)) {  
    //         resp.set_content("权限不足", "text/plain;charset=utf8");
    //         return;
    //     }

    //     std::vector<Question> questions;
    //     if (!ctl._model.GetAllQuestions(questions)) { 
    //         resp.set_content("获取题目列表失败", "text/plain;charset=utf8");
    //         return;
    //     }

    //     std::string html = "<html><head><meta charset=\"utf-8\">";
    //     html += "<script src=\"/js/login.js\" type=\"text/javascript\" charset=\"utf-8\"></script>";
    //  	html += "<script src=\"/js/login.js\"></script>";
    //     html += "<script src=\"/js/question.js\" type=\"text/javascript\" charset=\"utf-8\"></script>";
    //  	html += "<script src=\"/js/question.js\"></script>";

    //     // 添加“新增题目”按钮和表单
    //     html += "<h2>题目管理</h2>";
    //     html += "<h3>添加新题目</h3>";
    //     html += "<form onsubmit=\"submitQuestionForm(); return false;\">";
    //     html += "题号: <input type=\"text\" id=\"questionNumber\" required><br>";
    //     html += "标题: <input type=\"text\" id=\"title\" required><br>";
    //     html += "难度: <input type=\"text\" id=\"star\" required><br>";
    //     html += "描述: <textarea id=\"desc\"></textarea><br>";
    //     html += "代码头部: <textarea id=\"header\"></textarea><br>";
    //     html += "代码尾部: <textarea id=\"tail\"></textarea><br>";
    //     html += "测试输入: <textarea id=\"testInput\"></textarea><br>";
    //     html += "CPU 限制: <input type=\"number\" id=\"cpuLimit\" required><br>";
    //     html += "内存限制: <input type=\"number\" id=\"memLimit\" required><br>";
    //     html += "<button type=\"submit\">添加题目</button>";
    //     html += "</form>";

    //     // 现有题目列表
    //     html += "<h3>题目列表</h3>";
    //     html += "<script src=\"/js/login.js\" type=\"text/javascript\" charset=\"utf-8\"></script>";
    //     html += "<script src=\"/js/login.js\"></script>";
    //     for (const auto& q : questions) {
    //         html += "<tr>";
    //         html += "<td>" + q.number + "</td>";
    //         html += "<td>" + q.title + "</td>";
    //         html += "<td><button onclick=\"deleteQuestion('" + q.number + "')\">删除</button></td>";
    //         html += "</tr>";
    //     }
    //     html += "</table>";

    //     html += "</body></html>";
    //     resp.set_content(html, "text/html; charset=utf-8");
    // });

    svr.Post("/admin/add_question", [&ctl](const Request& req, Response& resp) {
        if (!ctl.verifyAdmin(req)) {
            resp.set_content("权限不足", "text/plain;charset=utf8");
            return;
        }

        // 解析 JSON 请求体
        Json::Reader reader;
        Json::Value body;
        if (!reader.parse(req.body, body)) {
            resp.set_content("请求数据解析失败", "text/plain;charset=utf8");
            return;
        }

        // 🔹 打印收到的数据
        std::cout << "收到的 JSON 数据: " << req.body << std::endl;

        // 提取题目信息
        Question q;
        q.number = body["number"].asInt();
        q.title = body["title"].asString();
        q.star = body["star"].asInt();
        q.desc = body["desc"].asString();
        q.header = body["header"].asString();
        q.tail = body["tail"].asString();
        q.test_input = body["test_input"].asString();
        q.cpu_commit = body["cpu_commit"].asInt();
        q.mem_commit = body["mem_commit"].asInt();

        // 🔹 打印提取的结构化数据
        std::cout << "解析后的数据: " << q.number << ", " << q.title << std::endl;

        // 调用数据库插入方法
        if (!ctl.AddQuestion(q)) {
            resp.set_content("添加题目失败", "text/plain;charset=utf8");
            return;
        }

        resp.set_content("添加成功", "text/plain;charset=utf8");
    });
    // svr.Post("/admin/add_question", [&ctl](const Request& req, Response& resp) 
    // {
    //     if (!ctl.verifyAdmin(req)) {
    //         resp.set_content("权限不足", "text/plain;charset=utf8");
    //         return;
    //     }

    //     // 解析 JSON 请求体
    //     Json::Reader reader;
    //     Json::Value body;
    //     if (!reader.parse(req.body, body)) {
    //         resp.set_content("请求数据解析失败", "text/plain;charset=utf8");
    //         return;
    //     }

    //     // 提取题目信息
    //     Question q;
    //     q.number = body["number"].asInt();
    //     q.title = body["title"].asString();
    //     q.star = body["star"].asInt();
    //     q.desc = body["desc"].asString();
    //     q.header = body["header"].asString();
    //     q.tail = body["tail"].asString();
    //     q.test_input = body["test_input"].asString();
    //     q.cpu_commit = body["cpu_commit"].asInt();
    //     q.mem_commit = body["mem_commit"].asInt();

    //     // 调用数据库插入方法
    //     if (!ctl.AddQuestion(q)) {
    //         resp.set_content("添加题目失败", "text/plain;charset=utf8");
    //         return;
    //     }

    //     resp.set_content("添加成功", "text/plain;charset=utf8");
    // });

    svr.Post("/admin/save_question", [&ctl](const Request& req, Response& resp) 
    {
        if (!ctl.verifyAdmin(req)) {
            resp.set_content("权限不足", "text/plain; charset=utf-8");
            return;
        }

        try {
            std::cout << "收到请求数据: " << req.body << std::endl; // ✅ 调试信息
            json j = json::parse(req.body); 
	        std::cerr << "json: " << j["number"] << std::endl;
            Question q;
            q.number = j["number"];
            q.title = j["title"];
            q.star = j["star"];
            q.cpu_commit = std::stoi(j["cpu_commit"].get<std::string>());
            q.mem_commit = std::stoi(j["mem_commit"].get<std::string>());
            q.desc = j["desc"];
            q.header = j["header"];
            q.tail = j["tail"];
            q.test_input = j["test_input"];

            if (!ctl._model.SaveQuestion(q)) { 
                resp.set_content("保存题目失败", "text/plain;charset=utf8");
                return;
            }
            resp.set_content("保存成功", "text/plain;charset=utf8");
        } catch (const std::exception& e) {
            std::cerr << "JSON 解析失败: " << e.what() << std::endl; // ✅ 打印异常信息
            resp.set_content("JSON 解析失败: " + std::string(e.what()), "text/plain;charset=utf8");
        }
    });

    svr.Post(R"(/admin/delete_question/(\d+))", [&ctl](const Request& req, Response& resp) 
    {
        if (!ctl.verifyAdmin(req)) {
            resp.set_content("权限不足", "text/plain;charset=utf8");
            return;
        }

        std::string number = req.matches[1];
        if (!ctl.DeleteQuestion(number)) {
            resp.set_content("删除失败", "text/plain;charset=utf8");
            return;
        }

        resp.set_content("删除成功", "text/plain;charset=utf8");
    });



    // 设置根目录
    svr.set_base_dir("./wwwroot");
    // 监听全体网卡，端口号固定8080
    svr.listen("0.0.0.0", 8080);
    return 0;
}
